package com.zb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.constant.GoodsConstant;
import com.zb.entity.*;
import com.zb.extend.FactoryProductExtend;
import com.zb.mapper.ZjProductMapper;
import com.zb.result.PageUtil;
import com.zb.service.*;
import com.zb.utils.RandomUtil;
import com.zb.view.ViewGoods;
import com.zb.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 产品表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-08-15
 */
@Service
public class ZjProductServiceImpl extends ServiceImpl<ZjProductMapper, ZjProduct> implements ZjProductService {
    @Resource
    private ZjProductMapper productMapper;
    @Resource
    private ZjBrandService brandService;
    @Resource
    private ZjProductSpecService specService;
    @Resource
    private ZjProductImageService imageService;
    @Resource
    private ZjProductIntroduceService introduceService;
    @Resource
    private ZjProductParamService paramService;
    @Resource
    private ZjProductCustomParamService customParamService;
    @Resource
    private ZjProductKnowledgeTypeService productKnowledgeTypeService;
    @Resource
    private ZjProductExtendPathService extendPathService;
    @Resource
    private ViewGoodsService viewGoodsService;
    @Resource
    private ZjFactoryProductService factoryProductService;

    // 新增或修改产品
    @Override
    @Transactional
    public void save(AccounLoginInfo loginInfo, GoodsVo goodsVo) {
        Assert.isTrue(null != goodsVo.getBrandId(), "商品品牌不能为空");
        Assert.isTrue(StringUtils.isNotBlank(goodsVo.getBrand()), "商品品牌不能为空");
        Assert.isTrue(null != goodsVo.getModel() && goodsVo.getModel().length() <= 100, "商品型号限制100个字符以内！", goodsVo.getModel());
        Assert.isTrue(null != goodsVo.getName() && goodsVo.getName().length() <= 100, "商品名称限制100个字符以内！", goodsVo.getName());
        ZjBrand brand = brandService.getById(goodsVo.getBrandId());
        Assert.isTrue(null != brand, "品牌ID参数[" + goodsVo.getBrandId() + "]的数据不存在！");
        Assert.isTrue(null == productMapper.existByModel(loginInfo.getCustAccId(), goodsVo.getId(), goodsVo.getModel()), "商品型号已重复！", goodsVo.getModel());
        if (StringUtils.isNotBlank(goodsVo.getCode())) {
            Assert.isTrue(null == productMapper.existByCode(loginInfo.getCustAccId(), goodsVo.getId(), goodsVo.getCode()), "商品编码已重复！", goodsVo.getCode());
        }
        if (StringUtils.isNotBlank(goodsVo.getItemNumber())) {
            Assert.isTrue(null == productMapper.existByItemNumber(loginInfo.getCustAccId(), goodsVo.getId(), goodsVo.getItemNumber()), "商品货号已重复！", goodsVo.getItemNumber());
        }
        ZjProduct product = new ZjProduct();
        BeanUtils.copyProperties(goodsVo, product);
        product.setBrand(brand.getName());
        product.setDisabled(goodsVo.getStatus());
        product.setTypeId(null == product.getTypeId()? 0L : product.getTypeId());
        product.setType(null == product.getType()? "" : product.getType());
        product.setEnabledRegister(null != product.getEnabledRegister() && product.getEnabledRegister());
        if (null != product.getId()) {
            this.updateById(product);
        } else {
            product.setId(IdWorker.getId());
            product.setCustAccId(loginInfo.getCustAccId());
            product.setName(StringUtils.isNotBlank(product.getName())? product.getName() : product.getModel());
            product.setCode(StringUtils.isNotBlank(product.getCode())? product.getCode() : "BM" + RandomUtil.random10());
            product.setItemNumber(StringUtils.isNotBlank(product.getItemNumber())? product.getItemNumber() : "HH" + RandomUtil.random10());
            product.setSource(GoodsConstant.SOURCE_1);
            product.setDeleted(false);
            product.setCreateEmpId(loginInfo.getId());
            product.setUpdateEmpId(loginInfo.getId());
            this.save(product);
        }
        specService.save(loginInfo.getCustAccId(), product.getId(), goodsVo.getSpecVos(), goodsVo.getDelSepcIds());
        imageService.save(loginInfo.getCustAccId(), product.getId(), goodsVo.getImageVos(), goodsVo.getDelImageIds());
        introduceService.save(loginInfo.getCustAccId(), product.getId(), goodsVo.getContent());
        paramService.save(loginInfo.getCustAccId(), product.getId(), goodsVo.getParamValVo());
        customParamService.save(loginInfo.getCustAccId(), product.getId(), goodsVo.getCustomParamVos(), goodsVo.getDelCustomParamIds());
        productKnowledgeTypeService.save(loginInfo.getCustAccId(), product.getId(), goodsVo.getKnowledgeTypeVos(), goodsVo.getDelKnowledgeTypeIds());
        extendPathService.save(loginInfo.getCustAccId(), product.getId(), goodsVo.getExtendPathVos(), goodsVo.getDelextendPathIds());
        factoryProductService.save(loginInfo.getCustAccId(), product.getId(), goodsVo.getFactoryIds());
    }


    // 获取产品列表
    @Override
    public Map<String, Object> getList(Long custAccId, GoodsSelectVo selectVo) {
        PageUtil.setPageLimit(selectVo);
        long count = productMapper.pageListCount(custAccId, selectVo);
        if (count <= 0) {
            return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), count, new ArrayList<>());
        }
        List<GoodsListVo> voList = productMapper.pageList(custAccId, selectVo);
        List<FactoryProductExtend> extendList = factoryProductService.getByProductIds(voList.stream().map(GoodsListVo::getId).toList());
        voList.forEach(t -> {
            t.setFactory(extendList.stream().filter(f -> Objects.equals(f.getProductId(), t.getId())).map(FactoryProductExtend::getFactory).collect(Collectors.joining("、")));
        });
        return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), count, voList);
    }

    // 根据产品ID获取产品详情
    @Override
    public GoodesDetailVo getProductDetail(Long id) {
        ZjProduct product = this.getById(id);
        Assert.isTrue(null != product, "产品参数[" + id + "]的数据不存在");
        List<ZjProductImage> imageList = imageService.getByProductId(id);
        return GoodesDetailVo.beanToVo(product, imageList.stream().map(ZjProductImage::getImage).toList());
    }

    // 批量启用或禁用产品
    @Override
    public void updateBatchDisabledByIds(List<Long> idList, boolean status) {
        productMapper.updateBatchDisabledByIds(idList, status);
    }

    // 根据品牌ID更新品牌名称
    @Override
    public void updateBrandByBrandId(Long brandId, String brand) {
        productMapper.updateBrandByBrandId(brandId, brand);
    }

    // 根据分类ID更新商品分类名称
    @Override
    public void updateTypeByTypeId(Long typeId, String type) {
        productMapper.updateTypeByTypeId(typeId, type);
    }

    // 根据商品单位ID更改商品单位名称
    @Override
    public void updateUnitByUnitId(Long unitId, String unit) {
        productMapper.updateUnitByUnitId(unitId, unit);
    }

    // 根据产品ID获取产品参数
    @Override
    public GoodsDetailParamVo getProductParam(Long id) {
        GoodsDetailParamVo paramVo =paramService.getByProductId(id);
        List<ZjProductCustomParam> productCustomParams = customParamService.getByProductId(id);

        List<GoodsCustomParamVo> customParamVos = productCustomParams.stream().map(vo -> {
            GoodsCustomParamVo customParam = new GoodsCustomParamVo();
            customParam.setId(vo.getId());
            customParam.setName(vo.getName());
            customParam.setVal(vo.getVal());
            return customParam;
        }).toList();
        if (null == paramVo) {
            paramVo = new GoodsDetailParamVo();
        }
        paramVo.setCustomParams(customParamVos);
        return paramVo;
    }

    // 根据产品ID获取产品修改前的信息
    @Override
    public GoodsVo getInfo(Long id) {
        ZjProduct product = this.getById(id);
        Assert.isTrue(null != product, "产品参数[" + id + "]的数据不存在！");
        GoodsVo vo = new GoodsVo();
        BeanUtils.copyProperties(product, vo);
        vo.setStatus(product.getDisabled());
        vo.setContent(introduceService.getByProductId(id));
        vo.setSpecVos(specService.getByProductId(id));
        vo.setImageVos(imageService.getByProductId(id).stream().map(img -> {
            return new GoodsImageVo(img.getId(), img.getImage());
        }).toList());
        vo.setParamValVo(paramService.getParamByProductId(id));
        vo.setCustomParamVos(customParamService.getByProductId(id).stream().map(param -> {
            return new GoodsCustomParamVo(param.getId(), param.getName(), param.getVal());
        }).toList());
        vo.setFactoryIds(factoryProductService.getByProductId(id).stream().map(ZjFactoryProduct::getFactoryId).toList());
        return vo;
    }

    // 根据产品ID获取产品信息
    @Override
    public List<GoodsInfo> getInfoByIds(List<Long> idList) {
        QueryWrapper<ZjProduct> wrapper = new QueryWrapper<>();
        wrapper.select("id", "gmt_create");
        wrapper.in("id", idList);
        return this.list(wrapper).stream().map(vo -> {
            GoodsInfo info = new GoodsInfo();
            info.setId(vo.getId());
            info.setDate(vo.getGmtCreate());
            return info;
        }).toList();
    }

    // 根据商家ID获取成品下拉数据
    @Override
    public Map<String, Object> pageSelect(Long custAccId, SelectVo selectVo) {
        PageUtil.setSelectPageLimit(selectVo);
        List<ZjProduct> products = productMapper.pageSelect(custAccId, selectVo);
        List<SelectGoodsVo> voList = products.stream().map(pro -> {
            SelectGoodsVo vo = new SelectGoodsVo(pro.getId(), pro.getName(), "");
            vo.setModel(pro.getModel());
            vo.setItemNumber(pro.getItemNumber());
            vo.setCode(pro.getCode());
            vo.setBrandId(pro.getBrandId());
            vo.setBrand(pro.getBrand());
            vo.setTypeId(pro.getTypeId());
            vo.setType(pro.getType());
            return vo;
        }).toList();

        List<Long> ids = voList.stream().map(SelectGoodsVo::getId).toList();
        List<ZjProductImage> images = imageService.getByProductIds(ids);
        voList.forEach(t -> {
            t.setImage(images.stream().filter(img -> Objects.equals(t.getId(), img.getProductId())).map(ZjProductImage::getImage).findFirst().orElse(""));
        });
        return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), productMapper.pageSelectCount(custAccId, selectVo), voList);
    }

    // 分页获取产品ID集合
    @Override
    public List<Long> pageGetIds(GoodsSelect goodsSelect) {
        return productMapper.pageGetIds(goodsSelect);
    }

    // 根据ID删除产品
    @Override
    @Transactional
    public void deleteBatchById(List<Long> ids) {
        specService.deleteBatchByProductId(ids);
        imageService.deleteBatchByProductId(ids);
        introduceService.removeByIds(ids);
        paramService.deleteBatchByProductId(ids);
        customParamService.deleteBatchByProductId(ids);
        productKnowledgeTypeService.deleteBatchByProductId(ids);
        extendPathService.deleteBatchByProductId(ids);
        factoryProductService.deleteByProductIds(ids);
        this.removeByIds(ids);
    }

    // 根据品牌ID查询关联产品的品牌
    @Override
    public List<String> getRelationBranByBrandIds(List<Long> brandIds) {
        if (null == brandIds || brandIds.isEmpty()) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjProduct> wrapper = new QueryWrapper<>();
        wrapper.select("brand");
        wrapper.in("brand_id", brandIds);
        return this.list(wrapper).stream().map(ZjProduct::getBrand).distinct().toList();
    }

    // 获取移动端商品品牌列表
    @Override
    public Map<String, Object> pageMobileGoodsBrandSelect(Long custAccId, FactorySelectVo selectVo) {
        PageUtil.setPageLimitMobile(selectVo);
        if (null != selectVo.getFactoryId() && selectVo.getFactoryId() > 0) {
            long count = productMapper.pageMobileGoodsBrandSelectCount(custAccId, selectVo);
            if (count <= 0) {
                return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), count, new ArrayList<>());
            }
            List<ZjProduct> productList = productMapper.pageMobileGoodsBrandSelect(custAccId, selectVo);
            return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), count, productList.stream().map(product -> {
                return new SelectResultVo(product.getBrandId(), product.getBrand());
            }).toList());
        }
        QueryWrapper<ZjProduct> wrapper = new QueryWrapper<>();
        wrapper.select("brand_id", "brand");
        wrapper.eq("cust_acc_id", custAccId);
        if (StringUtils.isNotBlank(selectVo.getName())) {
            wrapper.like("brand", selectVo.getName());
        }
        wrapper.groupBy("brand_id");
        Page<ZjProduct> page = this.page(new Page<>(selectVo.getPage(), selectVo.getLimit()), wrapper);
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), page.getRecords().stream().map(pro -> {
            return new SelectResultVo(pro.getBrandId(), pro.getBrand());
        }).toList());
    }

    // 根据商品分类Id获取关联商品型号
    @Override
    public List<ZjProduct> getRelationTypeByTypeIds(List<Long> typeIds) {
        return productMapper.getRelationTypeByTypeIds(typeIds);
    }

    // 获取移动端商品分类列表
    @Override
    public Map<String, Object> pageMobileGoodsTypeSelect(Long custAccId, Long brandId, FactorySelectVo selectVo) {
        PageUtil.setPageLimitMobile(selectVo);
        if (null != selectVo.getFactoryId() && selectVo.getFactoryId() > 0) {
            long count = productMapper.pageMobileGoodsTypeSelectCount(custAccId, brandId, selectVo);
            if (count <= 0) {
                return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), count, new ArrayList<>());
            }
            List<ZjProduct> productList = productMapper.pageMobileGoodsTypeSelect(custAccId, brandId, selectVo);
            return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), count, productList.stream().map(pro -> {
                return new SelectResultVo(pro.getTypeId(), pro.getType());
            }).toList());
        }
        QueryWrapper<ZjProduct> wrapper = new QueryWrapper<>();
        wrapper.select("type_id", "type");
        wrapper.eq("cust_acc_id", custAccId);
        if (null != brandId) {
            wrapper.eq("brand_id", brandId);
        }
        if (StringUtils.isNotBlank(selectVo.getName())) {
            wrapper.like("type", selectVo.getName());
        }
        wrapper.groupBy("type_id");
        Page<ZjProduct> page = this.page(new Page<>(selectVo.getPage(), selectVo.getLimit()), wrapper);
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), page.getRecords().stream().map(pro -> {
            return new SelectResultVo(pro.getTypeId(), pro.getType());
        }).toList());
    }

    // 根据商品单位ID获取关联商品型号
    @Override
    public List<ZjProduct> getRelationUnitByUnitIds(List<Long> unitIds) {
        return productMapper.getRelationUnitByUnitIds(unitIds);
    }

    // 根据商品ID&商品规格ID获取商品信息
    @Override
    public SelectGoodsVo getGoodsByIdAndSpecId(Long goodsId, Long goodsSpecId) {
        ZjProduct product = this.getById(goodsId);
        if (null == product) {
            return null;
        }
        SelectGoodsVo goodsVo = new SelectGoodsVo();
        goodsVo.setId(goodsId);
        goodsVo.setName(product.getName());
        goodsVo.setModel(product.getModel());
        goodsVo.setCode(product.getCode());
        goodsVo.setBrandId(product.getBrandId());
        goodsVo.setBrand(product.getBrand());
        goodsVo.setTypeId(product.getTypeId());
        goodsVo.setType(product.getType());

        List<GoodsSpecInfoVo> infoVoList = specService.getByProductId(goodsId);
        GoodsSpecInfoVo specInfoVo = infoVoList.stream().filter(f -> Objects.equals(f.getId(), goodsSpecId)).findFirst().orElse(null);
        if (null == specInfoVo) {
            return goodsVo;
        }
        goodsVo.setSpecId(specInfoVo.getId());
        goodsVo.setSpecName(specInfoVo.getName());
        goodsVo.setImage(specInfoVo.getImage());
        return goodsVo;
    }

    @Override
    public List<GoodsSpecInfoVo> getSpecByGoodsId(Long goodsId) {
        List<GoodsSpecInfoVo> infoVoList = specService.getByProductId(goodsId);
        return infoVoList;
    }

}
